/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

/*
 * SplashLoginFrame.java
 *
 * Created on 07 Feb 2011, 8:55:12 AM
 */
package za.co.pas.spaceandtime.view;

import za.co.pas.business.abstracts.AbstractView;
import java.awt.BorderLayout;
import java.awt.Color;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.text.ParseException;
import java.util.ListIterator;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import za.co.pas.business.constant.Constant;
import za.co.pas.business.data.Company;
import za.co.pas.spaceandtime.Main;
import za.co.pas.spaceandtime.component.FormattedEmailField;
import za.co.pas.spaceandtime.component.StatusPanel;
import za.co.pas.business.data.UserLoginDetails;
import za.co.pas.business.message.MessageObj;
import za.co.pas.business.message.StatusMessageObject;
import za.co.pas.business.model.ext.UserDetailModel;
import za.co.pas.business.mvc.BusinessMVC;

/**
 *
 * @author alabuschagne
 */
public class SplashLoginFrame extends JFrame implements AbstractView, PropertyChangeListener
{

    public static final int USERNAME = 0;
    public static final int PASSWORD = 1;
    private boolean ok = false;
    private FormattedEmailField userNameFormattedTextField = new FormattedEmailField();
    private Main main;
    private StatusPanel statusPanel;
    private UserLoginDetails userLoginDetails;

    private SplashLoginFrame()
    {
    }

    /** Creates new form SplashLoginFrame */
    public SplashLoginFrame(Main main)
    {
        super();
        this.main = main;
        statusPanel = new StatusPanel();
        initComponents();
        jPanel3.add(userNameFormattedTextField, BorderLayout.CENTER);
        getContentPane().add(statusPanel, BorderLayout.SOUTH);
        pack();
        setTitle("Space and Time : Login");
        Constant.mvc.addPropertyChangeListener(this);
    }

    /** This method is called from within the constructor to
     * initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is
     * always regenerated by the Form Editor.
     */
    @SuppressWarnings("unchecked")
    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
    private void initComponents() {

        splashPanel = new javax.swing.JPanel();
        jLabel4 = new javax.swing.JLabel();
        loginPanel = new javax.swing.JPanel();
        jLabel2 = new javax.swing.JLabel();
        passwordPasswordField = new javax.swing.JPasswordField();
        jLabel3 = new javax.swing.JLabel();
        loginButton = new javax.swing.JButton();
        jPanel3 = new javax.swing.JPanel();
        jLabel1 = new javax.swing.JLabel();
        companyCodeFormattedTextField = new javax.swing.JFormattedTextField();

        setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
        addWindowListener(new java.awt.event.WindowAdapter() {
            public void windowClosing(java.awt.event.WindowEvent evt) {
                formWindowClosing(evt);
            }
        });

        jLabel4.setHorizontalAlignment(javax.swing.SwingConstants.CENTER);
        jLabel4.setIcon(new javax.swing.ImageIcon(getClass().getResource("/za/co/pas/spaceandtime/resources/calendar.jpg"))); // NOI18N

        javax.swing.GroupLayout splashPanelLayout = new javax.swing.GroupLayout(splashPanel);
        splashPanel.setLayout(splashPanelLayout);
        splashPanelLayout.setHorizontalGroup(
            splashPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addComponent(jLabel4, javax.swing.GroupLayout.DEFAULT_SIZE, 400, Short.MAX_VALUE)
        );
        splashPanelLayout.setVerticalGroup(
            splashPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addComponent(jLabel4, javax.swing.GroupLayout.DEFAULT_SIZE, 219, Short.MAX_VALUE)
        );

        getContentPane().add(splashPanel, java.awt.BorderLayout.NORTH);

        loginPanel.setBorder(javax.swing.BorderFactory.createBevelBorder(javax.swing.border.BevelBorder.RAISED));

        jLabel2.setText("User name:");

        passwordPasswordField.addKeyListener(new java.awt.event.KeyAdapter() {
            public void keyPressed(java.awt.event.KeyEvent evt) {
                passwordPasswordFieldKeyPressed(evt);
            }
        });

        jLabel3.setText("Password:");

        loginButton.setText("Login");
        loginButton.setEnabled(false);
        loginButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                loginButtonActionPerformed(evt);
            }
        });

        jPanel3.setMaximumSize(new java.awt.Dimension(2147483647, 20));
        jPanel3.setMinimumSize(new java.awt.Dimension(0, 20));
        jPanel3.setPreferredSize(new java.awt.Dimension(222, 20));
        jPanel3.setLayout(new java.awt.BorderLayout());

        jLabel1.setText("Company code:");

        try {
            companyCodeFormattedTextField.setFormatterFactory(new javax.swing.text.DefaultFormatterFactory(new javax.swing.text.MaskFormatter("UUU####")));
        } catch (java.text.ParseException ex) {
            ex.printStackTrace();
        }

        javax.swing.GroupLayout loginPanelLayout = new javax.swing.GroupLayout(loginPanel);
        loginPanel.setLayout(loginPanelLayout);
        loginPanelLayout.setHorizontalGroup(
            loginPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, loginPanelLayout.createSequentialGroup()
                .addContainerGap()
                .addGroup(loginPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
                    .addComponent(loginButton)
                    .addGroup(javax.swing.GroupLayout.Alignment.LEADING, loginPanelLayout.createSequentialGroup()
                        .addGroup(loginPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                            .addComponent(jLabel3)
                            .addComponent(jLabel2)
                            .addComponent(jLabel1))
                        .addGap(18, 18, 18)
                        .addGroup(loginPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                            .addComponent(jPanel3, javax.swing.GroupLayout.DEFAULT_SIZE, 283, Short.MAX_VALUE)
                            .addComponent(passwordPasswordField, javax.swing.GroupLayout.DEFAULT_SIZE, 283, Short.MAX_VALUE)
                            .addComponent(companyCodeFormattedTextField, javax.swing.GroupLayout.DEFAULT_SIZE, 283, Short.MAX_VALUE))))
                .addContainerGap())
        );
        loginPanelLayout.setVerticalGroup(
            loginPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(loginPanelLayout.createSequentialGroup()
                .addContainerGap()
                .addGroup(loginPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(jLabel1)
                    .addComponent(companyCodeFormattedTextField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(loginPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
                    .addComponent(jPanel3, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(jLabel2))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(loginPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(jLabel3)
                    .addComponent(passwordPasswordField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(loginButton)
                .addContainerGap())
        );

        getContentPane().add(loginPanel, java.awt.BorderLayout.CENTER);

        pack();
    }// </editor-fold>//GEN-END:initComponents

    private void loginButtonActionPerformed(java.awt.event.ActionEvent evt)//GEN-FIRST:event_loginButtonActionPerformed
    {//GEN-HEADEREND:event_loginButtonActionPerformed
        try
        {
            userNameFormattedTextField.commitEdit();
            companyCodeFormattedTextField.commitEdit();
            if ((userNameFormattedTextField.isEditValid()) && (this.passwordPasswordField.getPassword().length > 0)
                    && companyCodeFormattedTextField.isEditValid())
            {
                UserDetailModel udm = (UserDetailModel) Constant.mvc.getModel(BusinessMVC.USER_DETAIL_MODEL);
                if (udm != null)
                {
                    userLoginDetails = udm.getUserLoginDetails((String) userNameFormattedTextField.getValue(), new String(passwordPasswordField.getPassword()));
                    if (userLoginDetails != null)
                    {
                        if (userLoginDetails.getEnabled())
                        {
                            if ((userLoginDetails.getCompanies() == null) || (userLoginDetails.getCompanies().isEmpty()))
                            {
                                JOptionPane.showMessageDialog(this, "This account is not linked to a company", "Warning", JOptionPane.WARNING_MESSAGE);
                            }
                            else
                            {
                                Company comp = null;
                                ListIterator<Company> it = userLoginDetails.getCompanies().listIterator();
                                while (it.hasNext())
                                {
                                    Company c = it.next();
                                    if (c.getCode().compareToIgnoreCase(this.companyCodeFormattedTextField.getText()) == 0)
                                    {
                                        comp = c;
                                        break;//out of while loop
                                    }
                                }
                                if (comp != null)
                                {
                                    userLoginDetails.setLoggedInCompany(comp);
                                    setOk(true);
                                    this.setVisible(false);
                                    main.hideSplash();
                                }
                                else
                                {
                                    JOptionPane.showMessageDialog(this, "Company not found", "Warning", JOptionPane.WARNING_MESSAGE);
                                }
                            }
                        }
                        else
                        {
                            JOptionPane.showMessageDialog(this, "This account is disabled", "Warning", JOptionPane.WARNING_MESSAGE);
                        }
                    }
                    else
                    {
                        JOptionPane.showMessageDialog(this, "Invalid username and password", "Warning", JOptionPane.WARNING_MESSAGE);
                    }
                }
                else
                {
                    JOptionPane.showMessageDialog(this, "Could not load user model", "Error", JOptionPane.ERROR_MESSAGE);
                }
            }
            else if (this.passwordPasswordField.getPassword().length == 0)
            {
                JOptionPane.showMessageDialog(this, "Password required", "Warning", JOptionPane.WARNING_MESSAGE);
            }
            else if (!userNameFormattedTextField.isEditValid())
            {
                JOptionPane.showMessageDialog(this, "Invalid user name", "Warning", JOptionPane.WARNING_MESSAGE);
            }
        }
        catch (ParseException ex)
        {
            JOptionPane.showMessageDialog(this, "Invalid email address.\n" + ex.getMessage(), "Warning", JOptionPane.WARNING_MESSAGE);
        }
    }//GEN-LAST:event_loginButtonActionPerformed

    private void formWindowClosing(java.awt.event.WindowEvent evt)//GEN-FIRST:event_formWindowClosing
    {//GEN-HEADEREND:event_formWindowClosing
        main.hideSplash();
    }//GEN-LAST:event_formWindowClosing

    private void passwordPasswordFieldKeyPressed(java.awt.event.KeyEvent evt)//GEN-FIRST:event_passwordPasswordFieldKeyPressed
    {//GEN-HEADEREND:event_passwordPasswordFieldKeyPressed
        if (evt.getKeyChar() == '\n')
        {
            loginButtonActionPerformed(null);
        }
    }//GEN-LAST:event_passwordPasswordFieldKeyPressed
    // Variables declaration - do not modify//GEN-BEGIN:variables
    private javax.swing.JFormattedTextField companyCodeFormattedTextField;
    private javax.swing.JLabel jLabel1;
    private javax.swing.JLabel jLabel2;
    private javax.swing.JLabel jLabel3;
    private javax.swing.JLabel jLabel4;
    private javax.swing.JPanel jPanel3;
    private javax.swing.JButton loginButton;
    private javax.swing.JPanel loginPanel;
    private javax.swing.JPasswordField passwordPasswordField;
    private javax.swing.JPanel splashPanel;
    // End of variables declaration//GEN-END:variables

    /**
     * @return the ok
     */
    public boolean isOk()
    {
        return ok;
    }

    /**
     * @param ok the ok to set
     */
    public void setOk(boolean ok)
    {
        this.ok = ok;
    }

    public UserLoginDetails getLoginDetails()
    {
        return userLoginDetails;
    }

    @Override
    public void modelPropertyChange(PropertyChangeEvent evt)
    {
        if (evt.getPropertyName().compareTo(MessageObj.STATUS_MESSAGE) == 0)
        {
            if (evt.getNewValue() instanceof StatusMessageObject)
            {
                StatusMessageObject smo = (StatusMessageObject) evt.getNewValue();
                if (smo.getMessage().compareTo(MessageObj.ALLOK) == 0)
                {
                    UserDetailModel udm = (UserDetailModel) Constant.mvc.getModel(BusinessMVC.USER_DETAIL_MODEL);
                    if (udm != null)
                    {
                        if (!udm.checkDB())
                        {
                            //init the whole db
                            Main.buildDB();
                        }
                    }
                    loginButton.setEnabled(true);
                }
                else if (smo.getMessage().compareTo(MessageObj.NOTOK) == 0)
                {
                    loginButton.setEnabled(false);
                    loginButton.setBackground(Color.red);
                }
            }
        }
    }

    @Override
    public void propertyChange(PropertyChangeEvent evt)
    {
        if (evt.getPropertyName().compareTo(MessageObj.STATUS_MESSAGE) == 0)
        {
            if (evt.getNewValue() instanceof StatusMessageObject)
            {
                StatusMessageObject smo = (StatusMessageObject) evt.getNewValue();
                if (smo.getMessage().compareTo(MessageObj.ALLOK) == 0)
                {
                    UserDetailModel udm = (UserDetailModel) Constant.mvc.getModel(BusinessMVC.USER_DETAIL_MODEL);
                    if (udm != null)
                    {
                        if (!udm.checkDB())
                        {
                            //init the whole db
                            Main.buildDB();
                        }
                    }
                    loginButton.setEnabled(true);
                }
                else if (smo.getMessage().compareTo(MessageObj.NOTOK) == 0)
                {
                    loginButton.setEnabled(false);
                    loginButton.setBackground(Color.red);
                }
            }
        }
    }

    @Override
    public boolean isDirty()
    {
        return false;
    }

    @Override
    public String getExtraTitle()
    {
        return null;
    }
}
